<?php

/**
 * @var $submit Zend_Form_Element_Submit
 */
class Contest_Form_Advanced extends Contest_Form_Abstract
{
	const SUBFORM_PHASE			= 'phase';
	const DEAULT_NUMBER_PHASE	= 3;
	private $_arrIsHidden		= array(false,false,false);

	public function __construct(array $options = null)
	{
		if( !empty($options) && isset($options['contest']) )
		{
			if( $options['contest'] instanceof Core_Model_Contest)
			{
				$this->_contestRow = $options['contest'];
			}
		}
		parent::__construct();
	}

	protected  function _hasBackButton() {
		return true;
	}

	protected function _initBegin()
	{
		$this->setAttrib('class', 'sm_form standard');
	}

	protected function _initFields()
	{
		$this->addElement('select','time_zone',array(
			'label' => $this->getTranslator()->_('LABEL_TIME_ZONE'),
            'class' => 'length_longest',
			'multiOptions' => array(
				'-12'	=> '(GMT -12:00) Eniwetok, Kwajalein',
				'-11'	=> '(GMT -11:00) Midway Island, Samoa',
				'-10'	=> '(GMT -10:00) Hawaii',
				'-9'	=> '(GMT -9:00) Alaska',
				'-8'	=> '(GMT -8:00) Pacific Time (US & Canada)',
				'-7'	=> '(GMT -7:00) Mountain Time (US & Canada)',
				'-6'	=> '(GMT -6:00) Central Time (US & Canada), Mexico City',
				'-5'	=> '(GMT -5:00) Eastern Time (US & Canada), Bogota, Lima',
				'-4'	=> '(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz',
				'-3'	=> '(GMT -3:00) Brazil, Buenos Aires, Georgetown',
				'-2'	=> '(GMT -2:00) Mid-Atlantic',
				'-1'	=> '(GMT -1:00) Azores, Cape Verde Islands',
				'0'		=> '(GMT) Western Europe Time, London, Lisbon, Casablanca',
				'+1'	=> '(GMT +1:00) Brussels, Copenhagen, Madrid, Paris',
				'+2'	=> '(GMT +2:00) Kaliningrad, South Africa',
				'+3'	=> '(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg',
				'+4'	=> '(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi',
				'+5'	=> '(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent',
				'+6'	=> '(GMT +6:00) Almaty, Dhaka, Colombo',
				'+7'	=> '(GMT +7:00) Bangkok, Hanoi, Jakarta',
				'+8'	=> '(GMT +8:00) Beijing, Perth, Singapore, Hong Kong',
				'+9'	=> '(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk',
				'+10'	=> '(GMT +10:00) Eastern Australia, Guam, Vladivostok',
				'+11'	=> '(GMT +11:00) Magadan, Solomon Islands, New Caledonia',
				'+12'	=> '(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka'
			),
			'value' => '0'
		));
		$this->time_zone->getDecorator('Label')->setOption('tagClass','sm_inside_main_form_label');

		for( $i = 0; $i < self::DEAULT_NUMBER_PHASE; $i++)
		{
			$subFormName	= self::SUBFORM_PHASE."[$i]";

			$subForm = new YouNet_Form_SubForm(array(
				'legend'	=> $this->_getLegendByPhase($i)
			));
			$subForm->getDecorator('Fieldset')->setOption('escape', false);
			if( $i != 0)
			{
				$this->_arrIsHidden[$i] = true;
			}

			$subForm->setIsArray(true);
			$subForm->addElement('text','name',array(
				'label'		=> $this->getTranslator()->_('PHASE_NAME'),
                'class'     => 'length_longest',
				'value'		=> $this->getTranslator()->_($this->_getDefaultNameByPhase($i)),
				'required'	=> true,
				'filters'	=> array('StringTrim')
			));
			$maxLengthValidator = new Zend_Validate_StringLength(array('max' => 63));
			$maxLengthValidator->setMessage('ERROR_PHASE_NAME_IS_TOO_LONG',Zend_Validate_StringLength::TOO_LONG);
			$subForm->name->addValidator($maxLengthValidator);

			$subForm->addElement('RichEditor','description',array(
				'label'		=> $this->getTranslator()->_('PHASE_DESCRIPTION'),
				'rows'		=> 4,
			));

			$subForm->addElement('text','date_start',array(
				'class'		=> 'calendar length_medium',
				'label'		=> $this->getTranslator()->_('PHASE_DATE_START'),
				'required'	=> true,
			));
			$subForm->date_start->addValidator(new Zend_Validate_Date(array(
                'format' => YouNet_Util::translate('DATE_FORMAT')
            )));

			$subForm->addElement('text','date_end',array(
				'class'		=> 'calendar length_medium',
				'label'		=> $this->getTranslator()->_('PHASE_DATE_END'),
				'required'	=> true
			));
			$subForm->date_end->addValidator(new Zend_Validate_Date(array(
                'format' => YouNet_Util::translate('DATE_FORMAT'),
                'locale'    => 'en'
            )));

			$subForm->addElement('multiCheckbox','options',array(
				'label'			=> $this->getTranslator()->_('PHASE_OPTIONS'),
				'multiOptions'	=> array(
					'is_allow_view'		=> $this->getTranslator()->_('PHASE_OPTION_ALLOW_VIEW'),
					'is_allow_submit'	=> $this->getTranslator()->_('PHASE_OPTION_ALLOW_SUBMIT'),
					'is_allow_vote'		=> $this->getTranslator()->_('PHASE_OPTION_ALLOW_VOTE'),
				),
				'value' => $this->_getDefaultOptionsByPhase($i)
			));
			$subForm->setElementsBelongTo($subFormName);
			$this->addSubForm($subForm,self::SUBFORM_PHASE.$i);
		}
	}

	private function _getIsUsedCheckbox($index,$isChecked = null, $isReadonly = false)
	{
		$checked = '';
		if( $index == 0)
		{
			$checked = 'checked="checked"';
		}
		else
		{
			if( isset($isChecked) )
			{
				if( $isChecked )
				{
					$checked = 'checked="checked"';
				}
			}
			else
			{
				if(isset($_POST['is_use_phase']) && !empty($_POST['is_use_phase'][$index]) )
				{
					$checked = 'checked="checked"';
				}
			}
		}
		$readonly = '';
		if( $index == 0 || $isReadonly === true)
		{
			$readonly = 'readonly="readonly"';
		}
		$checkbox = '<input type="checkbox" name="is_use_phase['.$index.']" value="1" '.$checked.' '.$readonly.'/>';
		return $checkbox;
	}
	private function _getLegendByPhase($index,$isChecked = null, $isReadonly = false)
	{
		$checkbox = $this->_getIsUsedCheckbox($index, $isChecked, $isReadonly);
		if( $index == 0)
		{
			return '<span>'.$checkbox.$this->getTranslator()->_('PHASE_NAME_LEGEND_SUBMISSION_PERIOD').'</span>';
		}
		elseif( $index == 1)
		{
			return '<span>'.$checkbox.$this->getTranslator()->_('PHASE_NAME_LEGEND_VOTING_PERIOD').'</span>';
		}
		elseif( $index == 2)
		{
			return '<span>'.$checkbox.$this->getTranslator()->_('PHASE_NAME_LEGEND_JUDGING_PERIOD').'</span>';
		}
		else
		{
			throw new Exception('The index of phase is out of array');
		}
	}

	private function _getDefaultNameByPhase($index)
	{
		if( $index == 0)
		{
			return 'PHASE_NAME_INITIAL_SUBMISSION_PERIOD';
		}
		elseif( $index == 1)
		{
			return 'PHASE_NAME_INITIAL_VOTING_PERIOD';
		}
		elseif( $index == 2)
		{
			return 'PHASE_NAME_INITIAL_JUDGING_PERIOD';
		} else {
			throw new Exception('The index of phase is out of array');
		}
	}
	/**
	 *
	 * @param int $index
	 * @return type
	 * @throws Exception
	 */
	private function _getDefaultOptionsByPhase($index)
	{
		if( $index == 0)
		{
			return array(
				'is_allow_view',
				'is_allow_submit',
                'is_allow_vote'
			);
		}
		elseif( $index == 1)
		{
			return array(
				'is_allow_view',
				'is_allow_submit',
                'is_allow_vote'
			);
		}
		elseif( $index == 2)
		{
			return array(
				'is_allow_view',
				'is_allow_submit',
                'is_allow_vote'
			);
		} else {
			throw new Exception('The index of phase is out of array');
		}
	}
	/**
	 *
	 * @param Core_Model_Contest $contestRow
	 * @return Contest_Form_Advanced
	 */
	public function fill(Core_Model_Contest $contestRow)
	{
		$data			= $contestRow->toArray();
		if( !isset($data['time_zone']) )
		{
			$data['time_zone'] = '0';
		}
		$dataPhase		= $contestRow->getArrayPhaseForPopulate();
		$this->populate(array_merge(
			$data,
			array(self::SUBFORM_PHASE => $dataPhase)
		));
		$i = 0;
		for(; $i < count($dataPhase); $i++)
		{
			$subForm = $this->getSubForm(self::SUBFORM_PHASE.$i);
            $phaseStart = $contestRow->isLimittedEdit(strtotime($dataPhase[$i]['date_start']));
			$subForm->setLegend(
				$this->_getLegendByPhase($i,true,$phaseStart)
			);
			$this->_arrIsHidden[$i] = false;
		}
		for(;$i < self::DEAULT_NUMBER_PHASE; $i++)
		{
			$subForm = $this->getSubForm(self::SUBFORM_PHASE.$i);
			$subForm->setLegend(
				$this->_getLegendByPhase($i,false,false)
			);
		}

		return $this;
	}

	public static function GetOptionsArray()
	{
		return array(
            'is_allow_view',
            'is_allow_submit',
            'is_allow_vote',
        );
	}

	public function render(Zend_View_Interface $view = null)
	{
		for( $i = 0; $i < self::DEAULT_NUMBER_PHASE; $i++)
		{
			$subForm = $this->getSubForm(self::SUBFORM_PHASE.$i);
			if( isset($_POST['is_use_phase']) && isset($_POST['is_use_phase'][$i]) )
			{
				$subForm->getDecorator('Fieldset')->setOption('class', '');
			}
			else
			{
				if( $this->_arrIsHidden[$i] )
				{
					$subForm->getDecorator('Fieldset')->setOption('class', 'hide_next');
				}
			}
		}
		if( isset($_POST['form_submitted']) )
		{
			if (!($this->_contestRow instanceof Core_Model_Contest))
			{
				throw new Exception('Need to set _contestRow to populate disable value');
			}
			if ( $this->_contestRow->isLimittedEdit() )
			{
				$dataPhase = $this->_contestRow->getArrayPhaseForPopulate();
				$data = $this->_contestRow->toArray();
				if (!isset($data['time_zone']))
				{
					$data['time_zone'] = '0';
				}

				$dataToPopulate = array();
				for ($i = 0; $i < count($dataPhase); $i++)
				{
					$dataToPopulate[$i] = array();
					$subForm = $this->getSubForm(self::SUBFORM_PHASE . $i);
					/* @var $phaseRow Core_Model_Phase */
					if (strtotime($dataPhase[$i]['date_start'].' 00:00:01') <= $this->_contestRow->getCurrentTimeWithTZ())
					{
						foreach (array('name','description', 'date_start', 'options') as $name)
						{
							$dataToPopulate[$i][$name] = $dataPhase[$i][$name];
						}

						if (strtotime($dataPhase[$i]['date_end'].' 23:59:59') <= $this->_contestRow->getCurrentTimeWithTZ())
						{
							$dataToPopulate[$i]['date_end'] = $dataPhase[$i]['date_end'];
						}
					}
				}
				$this->populate(array_merge(
					$_POST,
					array(
						'time_zone' => $data['time_zone']
					),
					array(
						self::SUBFORM_PHASE => $dataToPopulate
					)
				));
				$i = 0;
				for (; $i < count($dataPhase); $i++)
				{
					$subForm = $this->getSubForm(self::SUBFORM_PHASE . $i);
					$subForm->setLegend(
							$this->_getLegendByPhase($i, true, $this->_contestRow->isLimittedEdit())
					);
					$this->_arrIsHidden[$i] = false;
				}
				for (; $i < self::DEAULT_NUMBER_PHASE; $i++)
				{
					$subForm = $this->getSubForm(self::SUBFORM_PHASE . $i);
                    $isChecked = false;
                    if( isset($_POST['is_use_phase']) && isset($_POST['is_use_phase'][$i]) ){
                        $isChecked = true;
                    }
					$subForm->setLegend(
							$this->_getLegendByPhase($i, $isChecked, false)
					);
				}
			}
		}
		/*
		 * remove button cancel and back
	     */
        $this->removeButton();
		return parent::render($view);
	}

	public function disableFields()
	{
		$phaseList = $this->_contestRow->getPhasesList();

		for( $i = 0; $i < self::DEAULT_NUMBER_PHASE; $i++)
		{
			if( $phaseList->current() )
			{
				$subForm = $this->getSubForm(self::SUBFORM_PHASE.$i);
				/* @var $phaseRow Core_Model_Phase */
				$phaseRow = $phaseList->current();
				if( $phaseRow->date_start <= $this->_contestRow->getCurrentTimeWithTZ() )
				{
					$subForm->date_start->setAttrib('disable','disable');
					$subForm->date_start->setIgnore(true);
					$subForm->date_start->setRequired(false);

                    if( $phaseRow->date_end <= $this->_contestRow->getCurrentTimeWithTZ() )
					{
						$subForm->date_end->setAttrib('disable','disable');
						$subForm->date_end->setIgnore(true);
						$subForm->date_end->setRequired(false);
					}
				}
				$phaseList->next();
			}
		}
	}

		public function isValid($data,Core_Model_Contest $contestRow = null) {

		if( isset($data['time_zone']) && !$this->time_zone->isValid($data['time_zone']) )
		{
			$this->time_zone->addError($this->getTranslator()->translate('ERROR_INVALID_TIMEZONE'));
			$this->markAsError();
		}
		$phaseTable			= new Core_Model_DbTable_Phases();
		$phaseList			= $contestRow->getPhasesList();
		$arrPhaseValues		= $data[Contest_Form_Advanced::SUBFORM_PHASE];

		$n		= count($arrPhaseValues);
		for ($i = 0; $i < $n; $i++)
		{
			if( isset($_POST['is_use_phase']) && isset($_POST['is_use_phase'][$i]) )
			{
				$subForm = $this->getSubForm(Contest_Form_Advanced::SUBFORM_PHASE.$i);
				if( !empty($arrPhaseValues[$i]) )
				{
					if( !$subForm->isValid($arrPhaseValues[$i]) )
					{
						$this->markAsError();
					}
				}
			}
		}

		$lastTime = 0;
		for ($i = 0; $i < $n; $i++)
		{
			$phaseRow = null;
			if( !empty($phaseList) && $phaseList->current() )
			{
				$phaseRow				= $phaseList->current();
				$phaseList->next();
			}
			else
			{
                $phaseRow				= $phaseTable->createRow();
			}
			if( isset($_POST['is_use_phase']) && isset($_POST['is_use_phase'][$i]) )
			{
				if( !($phaseRow instanceof Core_Model_Phase) )
				{
					throw new Exception('Access is denied',302);
				}
				$subForm = $this->getSubForm(Contest_Form_Advanced::SUBFORM_PHASE.$i);

				$date_start = 0;
				if( !empty($arrPhaseValues[$i]['date_start']) )
				{
					$temp = strtotime($arrPhaseValues[$i]['date_start']);
					$date_start	= mktime(0, 0, 1, date('m', $temp), date('d', $temp), date('Y', $temp));
				}

				$date_end = 0;
				if( !empty($arrPhaseValues[$i]['date_end']) )
				{
					$temp = strtotime($arrPhaseValues[$i]['date_end']);
					$date_end		= mktime(23, 59, 59, date('m', $temp), date('d', $temp), date('Y', $temp));
				}

				//--Special validate date time
				$isError = false;
				$beginToday = ($data['time_zone'] >= 0) ? mktime(0,0,1) : mktime(0,0,1) - 24*3600;
				if( !$subForm->date_start->getIgnore() )
				{
					if( $phaseRow->date_start != $date_start )
					{
						if( $date_start < $beginToday )
						{
							$isError	= true;
							if( $beginToday > $lastTime )
							{
								$subForm->date_start->addError('Start date should be equal to or larger than today');
							}
						}
					}
					if( $date_start <  $lastTime )
					{
						$isError	= true;
						if( $beginToday  <= $lastTime)
						{
							$subForm->date_start->addError('Start date should be larger than end date of the previous phase');
						}
					}
				}
				//-- Reset $lastTime
				if( !$subForm->date_end->getIgnore() )
				{
					$lastTime				= $date_end;
					if( $phaseRow->date_end != $date_end )
					{
						if( $date_end < $beginToday )
						{
							$isError	= true;
							if( !empty($date_end) && $date_start < $beginToday )
							{
								$subForm->date_end->addError('End date should be equal to or larger than today');
							}
						}
					}

					if($date_end <  $date_start)
					{
						$isError = true;
						if( $date_start >= $beginToday )
						{
							$subForm->date_end->addError('End date should be equal to or larger than start date');
						}
					}
					elseif( $date_end == $date_start)
					{
						$isError = true;
						$subForm->date_end->addError('End date should be equal to or larger than start date');
					}
					if( $isError )
					{
						$this->markAsError();
						continue;
					}
				}
			}
		}
		return $this->isErrors();
	}

};